home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2004 #11 / Amiga Plus CD - 2004 - No. 11.iso / AmiSoft / Comm / mail / SpamFryer.lha / SpamFryer / YAM Support / rexx / SpamFryer.yam < prev   
Text File  |  2004-07-18  |  14KB  |  383 lines

  1. /*
  2.  *
  3.  * Usage: Rx SpamFryer.yam [<foldername>] [UNREAD] [ALL] [SILENT] [QUIET]
  4.  * Checks through emails in a folder and moves the unwanted ones.
  5.  *
  6.  * $VER: SpamFryer.yam 3.00 (18.07.04) by Allan Rasmussen
  7.  * Based upon SpamFryer.rexx by Simon N Goodwin
  8.  *
  9.  * Allan Rasmussen <allan (dot) tnt (at) post (dot) tele (dot) dk>
  10.  * Simon N Goodwin <amiga (at) studio (dot) co (dot) uk>
  11.  *
  12.  */
  13.  
  14. /******************************* CONFIGURATION BLOCK ********************************/
  15. /*                                                                                  */
  16. /*                Look for the Embed Rules further down in the script               */
  17.  
  18. spamFolder = 'Deleted'                 /* The folder to move spam mail to           */
  19. keepList   = 'YAM:SpamFryer.keeplist'  /* The path and name of your keep list       */
  20. loseList   = 'YAM:SpamFryer.loselist'  /* The path and name of your kill list       */
  21. refresh    = 'NO'                      /* Update folder index? 'YES' or 'NO'        */
  22. noDigits   = 'NO'                      /* Fry mails with digits in the To: address? */
  23.  
  24. /**************************** END OF CONFIGURATION BLOCK ****************************/
  25.  
  26. OPTIONS RESULTS
  27. OPTIONS FAILAT 10
  28.  
  29. PARSE ARG instring
  30. IF instring = '?' THEN DO
  31.   SAY 'Usage: Rx SpamFryer.yam [<foldername>] [UNREAD] [ALL] [SILENT] [QUIET]'
  32.   EXIT 0
  33. END
  34.  
  35. rcn      = 0
  36. keep     = 1
  37. lose     = 2
  38. gTo      = 1
  39. gFrom    = 2
  40. gReply   = 3
  41. gSubject = 4
  42. gEarly   = 5
  43.  
  44. list.keep = keepList
  45. list.lose = loseList
  46. listfield. = 0
  47. listpattern. = ''
  48.  
  49. IF UPPER(LEFT(noDigits,1)) = 'Y' THEN noDigits = 1
  50. ELSE noDigits = 0
  51.  
  52. IF ~SHOW('Ports','YAM') THEN SAY 'Please start YAM first.'
  53. ELSE DO
  54.   ADDRESS YAM
  55.   OPTIONS FAILAT 11
  56.   'FOLDERINFO STEM folder. 'spamFolder''
  57.   rcn = rc
  58.   OPTIONS FAILAT 10
  59.   IF rcn ~= 0 THEN moan = 'Could not get information for ' || spamFolder || '. Folder not found.'
  60.   ELSE DO
  61.     spamFolder = folder.name
  62.     verbose = 1
  63.     silent = 0
  64.     checkAll = 0
  65.     checkUnread = 0
  66.     IF instring = '' THEN args = 0
  67.     ELSE DO   /* extract and sort arguments - first extract... */
  68.       arg. = ''
  69.       args = 1
  70.       IF POS('"',instring)=0 THEN DO   /* if the argument line does not contain quotation signs... */
  71.         PARSE VAR instring arg.1 arg.2 arg.3 arg.4 arg.5 arg.6 .   /* the last variable is a dummy for validating the arguments */
  72.         DO WHILE arg.args ~= ''   /* count arguments */
  73.           args = args + 1
  74.         END
  75.         args = args - 1
  76.         IF LEFT(arg.args,1) >= '0' & LEFT(arg.args,1) <= '9' THEN args = args - 1   /* to compensate for strange behaviour by YAM */
  77.       END
  78.       ELSE DO   /* if the argument line contains quotation signs... */
  79.         PARSE VAR instring word1 '"' .   /* extract arguments in front of "folder name" */
  80.         IF word1 ~= '' THEN DO
  81.           PARSE VAR word1 arg.1 arg.2 arg.3 arg.4 arg.5 .   /* the last variable is a dummy for validating the arguments */
  82.           DO UNTIL arg.args = ''   /* count arguments in front of "folder name" */
  83.             args = args + 1
  84.           END
  85.         END
  86.         PARSE VAR instring '"'word1'"' word2   /* word1 is the words embrased by quotation signs - word2 contains all arguments after that */
  87.         DO WHILE word2 ~= ''   /* extract and count arguments after "folder name" */
  88.           PARSE VAR word2 arg.args word2
  89.           args = args + 1
  90.         END
  91.         t = args - 1
  92.         IF LEFT(arg.t,1) >= '0' & LEFT(arg.t,1) <= '9' THEN args = args - 1   /* to compensate for strange behaviour by YAM */
  93.         arg.args = word1   /* add the words embraced by quotation signs to the list of arguments */
  94.       END
  95.       IF args < 6 THEN DO   /* too many arguments breaks the script with an error message - else finally sort and act upon them... */
  96.         i = 1
  97.         DO WHILE UPPER(arg.i) ~= 'QUIET' & i < args
  98.           i = i + 1
  99.         END
  100.         IF UPPER(arg.i) = 'QUIET' THEN DO
  101.           args = args - 1
  102.           DO i = i TO args
  103.             t = i + 1
  104.             arg.i = arg.t
  105.           END
  106.           verbose = 0
  107.         END
  108.         i = 1
  109.         DO WHILE UPPER(arg.i) ~= 'SILENT' & i < args
  110.           i = i + 1
  111.         END
  112.         IF UPPER(arg.i) = 'SILENT' THEN DO
  113.           args = args - 1
  114.           DO i = i TO args
  115.             t = i + 1
  116.             arg.i = arg.t
  117.           END
  118.           silent = 1
  119.         END
  120.         i = 1
  121.         DO WHILE UPPER(arg.i) ~= 'ALL' & i < args
  122.           i = i + 1
  123.         END
  124.         IF UPPER(arg.i) = 'ALL' THEN DO
  125.           args = args - 1
  126.           DO i = i TO args
  127.             t = i + 1
  128.             arg.i = arg.t
  129.           END
  130.           checkAll = 1
  131.         END
  132.         i = 1
  133.         DO WHILE UPPER(arg.i) ~= 'UNREAD' & i < args
  134.           i = i + 1
  135.         END
  136.         IF UPPER(arg.i) = 'UNREAD' THEN DO
  137.           args = args - 1
  138.           DO i = i TO args
  139.             t = i + 1
  140.             arg.i = arg.t
  141.           END
  142.           checkUnread = 1
  143.         END
  144.       END
  145.     END
  146.     IF args > 1 THEN DO
  147.       rcn = 10
  148.       moan = 'Bad usage.'
  149.     END
  150.     ELSE DO
  151.       FOLDERINFO STEM folder.
  152.       homeFolder = folder.name
  153.       IF args THEN testFolder = arg.1
  154.       ELSE testFolder = homeFolder
  155.       OPTIONS FAILAT 11
  156.       'FOLDERINFO STEM folder. 'testFolder''
  157.       rcn = rc
  158.       OPTIONS FAILAT 10
  159.       IF rcn ~= 0 THEN moan = 'Could not get information for ' || testFolder || '. Folder not found.'
  160.       ELSE DO
  161.         testFolder = folder.name
  162.         IF testFolder = spamFolder THEN DO
  163.           rcn = 10
  164.           moan = 'Source and destination must be different.'
  165.         END
  166.         ELSE DO
  167.           todo = folder.new
  168.           IF checkUnread THEN todo = folder.unread
  169.           IF checkAll THEN todo = folder.total
  170.           IF todo = 0 THEN DO
  171.             moan = 'No'
  172.             IF ~checkAll & ~checkUnread THEN moan = moan || ' new'
  173.             IF ~checkAll & checkUnread THEN moan = moan || ' unread'
  174.             moan = moan || ' messages to check in '||testFolder||'.'
  175.           END
  176.           ELSE DO
  177.             IF verbose & ~silent THEN SAY 'Embed rules...'
  178.  
  179.             /****************************************************************/
  180.             /* Embed rules here, or put them in keeplist and loselist files */
  181.             /* Let through mails specifically about this program */
  182.  
  183.             CALL keep_rule "Subject: SpamFryer"
  184.             CALL keep_rule "Subject: Spam Frier" /* Allow various spellings */
  185.             CALL keep_rule "Subject: Spam Fryer"
  186.  
  187.             /* These three rules catch a lot of spam */
  188.  
  189.             CALL lose_rule "Subject: *SPAM*"    /* Premarked by mail server */
  190.             CALL lose_rule "To: www."           /* Idiot mailing web server */
  191.             CALL lose_rule "To: undisclosed-recipients" /* A spam indicator */
  192.  
  193.             /* These all signify a HTML mail with no plain text - i.e. spam */
  194.  
  195.             CALL lose_rule "Early-Ref: </"
  196.             CALL lose_rule "Early-Ref: <HTML>"
  197.             CALL lose_rule "Early-Ref: text/html"
  198.  
  199.             /****************************************************************/
  200.  
  201.             DO type = keep TO lose
  202.               IF list.type ~='' THEN DO
  203.                 IF ~OPEN(list,list.type,'R') THEN moan = list.type 'not found.'
  204.                 ELSE DO
  205.                   IF verbose & ~silent THEN SAY list.type || '...'
  206.                   iterations = 0
  207.                   counter = 0
  208.                   DO WHILE ~EOF(list)
  209.                     iterations = iterations + 1
  210.                     listerror = 0
  211.                     CALL learn_rule READLN(list), type
  212.                     IF listerror THEN DO
  213.                       sigh = 'Error in' list.type || '. Line' iterations 'skipped.'
  214.                       SAY sigh
  215.                       'REQUEST "'sigh'" "_Ok"'
  216.                     END
  217.                   END
  218.                   CALL CLOSE(list)
  219.                   IF counter = 0 THEN moan = list.type 'not loaded.'
  220.                   ELSE moan = list.type 'loaded.'
  221.                 END
  222.                 IF verbose THEN SAY moan
  223.               END
  224.             END
  225.  
  226.             IF verbose THEN SAY 'Filtering ' || testFolder || '...'
  227.             'SETFOLDER 'testFolder''
  228.             checked = 0
  229.             zapped = 0
  230.             DO n = 1 TO folder.total WHILE checked < todo & rcn = 0
  231.               SETMAIL folder.total-n
  232.               MAILINFO STEM mail.
  233.               IF checkAll | mail.status = 'N' | (checkUnread & mail.status = 'U') THEN DO
  234.                 checked = checked + 1
  235.                 dating = 0
  236.                 bad = 0
  237.                 good = 0
  238.                 body = 0
  239.                 IF ~OPEN(mail,mail.filename,'R') THEN DO
  240.                   moan = 'Could not get information for ' || mail.filename || '. File not found.'
  241.                   SAY moan
  242.                   'REQUEST "'moan'" "_Ok|_Abort"'
  243.                   IF RESULT = 0 THEN rcn = 10
  244.                 END
  245.                 ELSE DO
  246.                   DO WHILE ~EOF(mail) & ~good & body<13
  247.                     instring = READLN(mail)
  248.                     inCaps = UPPER(instring)
  249.                     IF body > 0 | instring = '' THEN body = body + 1
  250.                     ELSE DO
  251.                       IF LEFT(instring,4) = 'To: ' THEN DO
  252.                         IF noDigits THEN DO i = 0 to 9
  253.                           IF POS(i,instring)>0 THEN bad=1
  254.                         END
  255.                         DO i = 1 TO listfield.keep.gTo
  256.                           IF POS(listpattern.keep.gTo.i,inCaps)>0 THEN good=1
  257.                         END
  258.                         DO i = 1 TO listfield.lose.gTo
  259.                           IF POS(listpattern.lose.gTo.i,inCaps)>0 THEN bad=1
  260.                         END
  261.                       END
  262.                       IF LEFT(instring,6) = 'From: ' THEN DO
  263.                         DO i = 1 TO listfield.keep.gFrom
  264.                           IF POS(listpattern.keep.gFrom.i,inCaps)>0 THEN good=1
  265.                         END
  266.                         DO i = 1 TO listfield.lose.gFrom
  267.                           IF POS(listpattern.lose.gFrom.i,inCaps)>0 THEN bad=1
  268.                         END
  269.                       END
  270.                       IF LEFT(instring,10) = 'Reply-To: ' THEN DO
  271.                         DO i = 1 TO listfield.keep.gReply
  272.                           IF POS(listpattern.keep.gReply.i,inCaps)>0 THEN good=1
  273.                         END
  274.                         DO i = 1 TO listfield.lose.gReply
  275.                           IF POS(listpattern.lose.gReply.i,inCaps)>0 THEN bad=1
  276.                         END
  277.                       END
  278.                       IF LEFT(instring,9) = 'Subject: ' THEN DO
  279.                         DO i = 1 TO listfield.keep.gSubject
  280.                           IF POS(listpattern.keep.gSubject.i,inCaps)>0 THEN good=1
  281.                         END
  282.                         DO i = 1 TO listfield.lose.gSubject
  283.                           IF POS(listpattern.lose.gSubject.i,inCaps)>0 THEN bad=1
  284.                         END
  285.                       END
  286.                     END
  287.                     IF POS(' DATING ',inCaps)>0 THEN dating = dating + 1;
  288.                     IF POS('CREATED BY WOMEN',inCaps)>0 THEN dating = dating + 1
  289.                     DO i = 1 to listfield.keep.gEarly
  290.                       IF POS(listpattern.keep.gEarly.i,inCaps)>0 THEN good=1
  291.                     END
  292.                     DO i = 1 to listfield.lose.gEarly
  293.                       IF POS(listpattern.lose.gEarly.i,inCaps)>0 THEN bad=1
  294.                     END
  295.                   END
  296.                   CALL CLOSE(mail)
  297.                 END
  298.                 IF ~good & (bad | dating>1) THEN DO
  299.                   LISTSELECT NONE
  300.                   LISTSELECT folder.total-n
  301.                   'MAILMOVE 'spamFolder''
  302.                   zapped = zapped + 1
  303.                 END
  304.               END
  305.             END
  306.             moan = 'Moved' zapped 'out of' checked
  307.             IF ~checkAll & ~checkUnread THEN moan = moan || ' new'
  308.             IF ~checkAll & checkUnread THEN moan = moan || ' unread'
  309.             moan = moan || ' message'
  310.             IF todo ~= 1 THEN moan = moan || 's'
  311.             moan = moan || '.'
  312.             IF testFolder = homeFolder THEN DO
  313.               IF UPPER(LEFT(refresh,1)) ~= 'N' THEN MAILUPDATE
  314.             END
  315.             ELSE DO
  316.               'SETFOLDER 'homeFolder''
  317.             END
  318.           END
  319.         END
  320.       END
  321.     END
  322.   END
  323.   IF verbose + rcn > 0 THEN DO
  324.     SAY moan
  325.     'REQUEST "'moan'" "_Ok"'
  326.   END
  327. END
  328. EXIT rcn
  329.  
  330. keep_rule:
  331.   listerror = 0
  332.   CALL learn_rule arg(1), keep
  333.   IF listerror THEN DO
  334.     sigh = 'Rule "' arg(1) '" skipped.'
  335.     SAY sigh
  336.     'REQUEST "'sigh'" "_Ok"'
  337.   END
  338. RETURN 1
  339.  
  340. lose_rule:
  341.   listerror = 0
  342.   CALL learn_rule arg(1), lose
  343.   IF listerror THEN DO
  344.     sigh = 'Rule "' arg(1) '" skipped.'
  345.     SAY sigh
  346.     'REQUEST "'sigh'" "_Ok"'
  347.   END
  348. RETURN 1
  349.  
  350. learn_rule:
  351.   instring = UPPER(arg(1))
  352.   kind = arg(2)
  353.   PARSE VAR instring word instring   /* separate the first word from the rest */
  354.   word = STRIP(word)
  355.   instring = STRIP(instring)
  356.   IF word = "//" THEN RETURN 1   /* Allow C++ comments in the configuration lines */
  357.   IF instring = '' THEN DO
  358.     IF word ~= '' THEN listerror = 1   /* Error if there is only one word in the string */
  359.   END
  360.   ELSE DO
  361.     field = 0
  362.     IF RIGHT(word,1) ~= ':' THEN word = word || ':'
  363.     IF word = 'TO:' THEN field = gTo
  364.     IF word = 'FROM:' THEN field = gFrom
  365.     IF word = 'REPLY-TO:' THEN field = gReply
  366.     IF word = 'SUBJECT:' THEN field = gSubject
  367.     IF word = 'EARLY-REF:' THEN field = gEarly
  368.     IF field = 0 THEN listerror = 1   /* Error, unexpected first word on line */
  369.     ELSE DO
  370.       IF RIGHT(instring,1) = "'" & LEFT(instring,1)="'" THEN instring = STRIP(instring,'B',"'")
  371.       IF RIGHT(instring,1) = '"' & LEFT(instring,1)='"' THEN instring = STRIP(instring,'B','"')
  372.       listfield.kind.field = listfield.kind.field + 1   /* count entries in each field parameter for each list */
  373.       counter = listfield.kind.field
  374.       listpattern.kind.field.counter = instring   /* Store search pattern */
  375.       IF verbose & ~silent THEN DO
  376.         IF kind = keep THEN sigh = 'KEEP'
  377.         ELSE sigh = 'LOSE'
  378.         SAY sigh word instring
  379.       END
  380.     END
  381.   END
  382. RETURN 1
  383.